/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package core.io;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;

/**
 *
 * @author Dung Pham
 */
public class MessageRequestDecoder extends CumulativeProtocolDecoder{
    private static final byte PROTOCOL_INT = 0x0a;

    @Override
    protected boolean doDecode(IoSession session, IoBuffer buffer, ProtocolDecoderOutput decoderOutput) throws Exception {
        if (!session.containsAttribute(Attribute.SESSION_INFOR)) {
            return doHandShakeClient(session, buffer, decoderOutput);
        }
        if (session.containsAttribute(Attribute.PROTOCOL_10_ATTRIBUTE)
                && buffer.prefixedDataAvailable(4, Message.MAX_MESSAGE_LENGTH_PROTOCOL_10)) {
            return doDecodeProtocol10(session, buffer, decoderOutput);
        } 
        return false;
    }
    
    private boolean doHandShakeClient(IoSession ioSession, IoBuffer buffer, ProtocolDecoderOutput outPut) {
        SessionAttribute sessionInfo = new SessionAttribute();
        //byte dau tien dung de xac dinh protocol.
        byte flag = buffer.get(0);
        if (flag == PROTOCOL_INT) {           
            buffer.get();
            long key = buffer.getLong();
            Session iwinSession = new Session(ioSession, sessionInfo);
            sessionInfo.setIoSession(iwinSession);
            ioSession.setAttribute(Attribute.EXCHANGE_KEY_ATTRIBUTE, new ExchangeKeyAttribute(key));
            // truong hop protocol 10 them attribute nay de xac dinh.
            if (flag == PROTOCOL_INT) {
                ioSession.setAttribute(Attribute.PROTOCOL_10_ATTRIBUTE, PROTOCOL_INT);
            }
            return true;
        } else {
            return false;
        }
    }
    
    private boolean doDecodeProtocol10(IoSession session, IoBuffer buffer, ProtocolDecoderOutput outPut) throws IOException {
        Message message = null;
        int datalengh = buffer.getInt();
        byte encryptStatus = buffer.get();
        int cmdId = -1;
        if (datalengh > 0) {
            byte[] data = new byte[datalengh - 1];
            buffer.get(data);
            ExchangeKeyAttribute exchangeKeyAttr = (ExchangeKeyAttribute) session.getAttribute(Attribute.EXCHANGE_KEY_ATTRIBUTE);
            ByteArrayInputStream inputStream;
            byte[] messageData;
            if (encryptStatus == 0) {
                inputStream = new ByteArrayInputStream(data);
            } else {
                inputStream = new ByteArrayInputStream(exchangeKeyAttr.getTea().decrypt(data));
            }
            DataInputStream dis = new DataInputStream(inputStream);
            cmdId = dis.readInt();
            System.out.println("command: " + cmdId);            
            messageData = new byte[dis.available()];
            System.out.println("size: " + messageData.length);
            dis.read(messageData);
            message = new Message(cmdId, messageData);
            dis.close();
            inputStream.close();
            data = null;
        }

        if (message != null) {
            //session.setAttribute(Attribute.LAST_ACTIVE_TIME, System.currentTimeMillis());
            outPut.write(message);
            return true;
        } else {
            return false;
        }
    }
}
